﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CkSoftware.GroupMe.Sdk.Bot;
using CkSoftware.GroupMe.Sdk.Core.Dao;

namespace CkSoftware.GroupMe.Sdk.TestWeb.Helpers
{
	public static class BotHelper
	{
		private const string BotStartedConfigKey = "BotStarted";

		private const string BotInstanceConfigKey = "GroupMeBotInstance";

		public static bool IsBotStarted()
		{
			return SessionConfiguration.GetConfigValue<bool>(BotStartedConfigKey);
		}

		public static async Task StartBot(string botName, string avatarUrl, string callbackUrl)
		{
			if (IsBotStarted())
			{
				throw new InvalidOperationException("You cannot start more than one bot simultaneousely.");
			}
			
			GroupMeBot bot = GroupMeHelper.CreateBotForSessionConfig(botName);
			
			if (!string.IsNullOrEmpty(avatarUrl))
			{
				var image = await GroupMeHelper.CreateImage(avatarUrl);

				bot.WithAvatar(image.Url);
			}
			
			if (!string.IsNullOrEmpty(callbackUrl))
			{
				bot.WithCallback(callbackUrl);
			}

			await bot.StartBotAsync();

			SessionConfiguration.SetConfigValue(BotStartedConfigKey, true);
			SessionConfiguration.SetConfigValue(BotInstanceConfigKey, bot);
		}

		public static async Task SendMessage(string message, string attachmentImageUrl)
		{
			if (!IsBotStarted())
			{
				throw new InvalidOperationException("You cannot send a message if there is no bot started.");
			}

			var bot = SessionConfiguration.GetConfigValue<GroupMeBot>(BotInstanceConfigKey);
			var botMessage = bot.SendMessage(message);

			if (!string.IsNullOrEmpty(attachmentImageUrl))
			{
				var image = await GroupMeHelper.CreateImage(attachmentImageUrl);
				botMessage.WithAttachment(new GroupMeImageAttachment {Url = image.Url});
			}

			await botMessage.SubmitAsync();
		}

		public static async Task DestroyBot()
		{
			if (!IsBotStarted())
			{
				throw new InvalidOperationException("You cannot destroy a bot if there is no bot started.");
			}

			var bot = SessionConfiguration.GetConfigValue<GroupMeBot>(BotInstanceConfigKey);
			await bot.DestroyBotAsync();

			SessionConfiguration.SetConfigValue(BotStartedConfigKey, false);
			SessionConfiguration.SetConfigValue(BotInstanceConfigKey, (GroupMeBot) null);
		}

		public static async Task<IEnumerable<GroupMeBot>> GetAllBots()
		{
			try
			{
				return await GroupMeHelper.GetAllBotsForSessionConfig();
			}
			catch (NotSupportedException)
			{
				return Enumerable.Empty<GroupMeBot>();
			}
		}

		public static async Task DestroyBotWithId(string botId)
		{
			var allBots = await GroupMeHelper.GetAllBotsForSessionConfig();
			var botToDelete = allBots.SingleOrDefault(bot => bot.Data.Id == botId);

			if (botToDelete == null)
			{
				throw new ArgumentException("The supplied bot-id was not found.", "botId");
			}

			await botToDelete.DestroyBotAsync();
		}

		public static async Task SetBotWithIdAsCurrentBot(string botId)
		{
			if (IsBotStarted())
			{
				throw new InvalidOperationException("You cannot start more than one bot simultaneousely.");
			}
			
			var allBots = await GroupMeHelper.GetAllBotsForSessionConfig();
			var botToUse = allBots.SingleOrDefault(bot => bot.Data.Id == botId);

			if (botToUse == null)
			{
				throw new ArgumentException("The supplied bot-id was not found.", "botId");
			}

			SessionConfiguration.SetConfigValue(BotStartedConfigKey, true);
			SessionConfiguration.SetConfigValue(BotInstanceConfigKey, botToUse);
		}
	}
}